﻿mapClass = function (Width, Height) {

    this.innerMap = null;

    this.innerCollidedParticles = new function () {
        this._innerHashTable = new Array();

        this.all = function () {
            return this._innerHashTable;
        }

        this.add = function (posX, posY) {
            this._innerHashTable[posX + "," + posY] = [posX, posY];
        }

        this.get = function (index) {
            return this._innerHashTable[index];
        }

    }

    //A simple array of all particles in the map. 
    this.innerParticles = new function () {

        this._particles = new Array();

        this.length = function () {
            return this._particles.length;
        }

        this.add = function (posX, posY, newObject) {
            this._particles[this._particles.length] = [posX, posY, newObject];
        }

        this.get = function (index) {
            return this._particles[index];
        }

        this.getParticle = function (index) {
            return _particles[index][3];
        }

        this.getParticleX = function (index) {
            return _particles[index][0];
        }

        this.getParticleY = function (index) {
            return _particles[index][1];
        }

        this.clear = function () {
            _particles = new Array();
        }

    }

    //Constructor
    function Constructor() {
        innerMap = new Array(Width);
        for (var i = 0; i <= Width; i++) {
            innerMap[i] = new Array(Height);
        }
    }

    this.hasParticle = function (posX, posY) {

        var posX_Parsed = parseInt(posX);
        var posY_Parsed = parseInt(posY);

        if (innerMap[posX_Parsed] == null || innerMap[posX_Parsed][posY_Parsed] == null) {
            return false;
        }
        else {
            return true;
        }

    }

    /*@  Will only ever return a single object @*/
    this.getParticle = function (posX, posY) {

        var posX_Parsed = parseInt(posX);
        var posY_Parsed = parseInt(posY);

        if (this.hasParticle(posX, posY)) {
            return innerMap[posX_Parsed][posY_Parsed][0];
        }
        return false;

    }

    /*@ Will return an array of particle that are occupying this space @*/
    this.getParticleMulti = function (posX, posY) {

        var posX_Parsed = parseInt(posX);
        var posY_Parsed = parseInt(posY);

        if (this.hasParticle(posX_Parsed, posY_Parsed)) {
            return innerMap[posX][posY];
        }
        return false;

    }

    this.setParticle = function (posX, posY, newObject) {

        var posX_Parsed = parseInt(posX);
        var posY_Parsed = parseInt(posY);

        //off side of screen
        if (posX > this.Width || posY > this.Height || posX < 0 || posY < 0) {
            this.addOffScreen(posX, posY, newObject);
            return true;
        }
        if (!this.hasParticle(posX, posY)) {
            innerMap[posX_Parsed][posY_Parsed] = new Array();
        }
        innerMap[posX_Parsed][posY_Parsed][0] = newObject;
        this.innerParticles.add(posX, posY, newObject);
        return true;

    }

    this.addParticle = function (posX, posY, newObject) {

        var posX_Parsed = parseInt(posX);
        var posY_Parsed = parseInt(posY);

        //off side of screen
        if (posX_Parsed + 1 >= Width || posY_Parsed + 1 >= Height || posX < 0 || posY < 0) {
            this.addOffScreen(posX, posY, newObject);
            return true;
        }

        if (!this.hasParticle(posX, posY)) {
            innerMap[posX_Parsed][posY_Parsed] = new Array();
        } else {
            this.innerCollidedParticles.add(posX_Parsed, posY_Parsed);
        }
        var thisMapPosition = innerMap[posX_Parsed][posY_Parsed];
        thisMapPosition[thisMapPosition.length] = newObject;
        this.innerParticles.add(posX, posY, newObject);
        return true;

    }

    this.removeParticle = function (posX, posY, removeObject) {

        var posX_Parsed = parseInt(posX);
        var posY_Parsed = parseInt(posY);

        var thisMapPosition = innerMap[posX_Parsed][posY_Parsed];
        var newThisMapPosition = new Array();
        var idx = 0;

        for (var i = 0; i < thisMapPosition.length; i++) {

            if (thisMapPosition[i] != removeObject) {
                newThisMapPosition[idx] = thisMapPosition[i];
                idx++;
            }

        }
        innerMap[posX_Parsed][posY_Parsed] = newThisMapPosition;

        return true;

    }

    //Add a particle to outside the map.
    this.addOffScreen = function (posX, posY, newObject) {
        this.innerParticles.add(posX, posY, newObject);
        
        var posX_Parsed = parseInt(posX);
        var posY_Parsed = parseInt(posY);

        if (posX + 1 >= Width || posX < 0) {
            newObject._velocityX = -newObject._velocityX;
        }
        if (posY + 1 >= Height || posY < 0) {
            newObject._velocityY = -newObject._velocityY;
        }

    }

    this.dispose = function () {
    }

    //Call the constructor
    Constructor()
}